﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace HospitalMedicineTraceability
{
    /// <summary>
    /// 带选择框的ComboBox
    /// </summary>
    public partial class ComboBoxChecked : ComboBox
    {
        public CheckedListBox list = new CheckedListBox();
        public Dictionary<object, string> SelectItems = new Dictionary<object, string>();
        #region IsMultiSelect
        private bool isMultiSelect = false;
        [Description("设置是否允许多选")]
        public bool IsMultiSelect
        {
            get { return isMultiSelect; }
            set
            {
                isMultiSelect = value;
                if (isMultiSelect)
                {
                    //只有设置这个属性为OwnerDrawFixed才可让重画起作用 
                    this.DrawMode = DrawMode.OwnerDrawFixed;
                    this.ItemHeight = 15;
                    this.IntegralHeight = false;
                    this.DoubleBuffered = true;
                    this.DroppedDown = false;
                    this.DropDownHeight = 1;
                    this.DropDownStyle = ComboBoxStyle.DropDown;
                    list.CheckOnClick = true;
                    list.ItemCheck += new ItemCheckEventHandler(list_ItemCheck);
                    list.MouseUp += new MouseEventHandler(list_MouseUp);
                    list.MouseLeave += new EventHandler(list_MouseLeave);
                    list.BorderStyle = BorderStyle.Fixed3D;
                    list.Visible = false;
                }
                else
                {
                    //只有设置这个属性为Normal才可让重画不起作用 
                    this.DrawMode = DrawMode.Normal;
                    this.IntegralHeight = true;
                    this.DoubleBuffered = true;
                    this.DropDownHeight = 106;
                }
            }
        }
        #endregion
        #region SelectedValues
        private string[] selectedValues = null;
        [Description("选择项的Value值(数组)")]
        public string[] SelectedValues
        {
            get
            {
                if (IsMultiSelect)
                {
                    string str = "";
                    foreach (KeyValuePair<object, string> m in SelectItems)
                    {
                        str = str + m.Key.ToString() + ",";
                    }
                    string[] array = str.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    return array;
                } return selectedValues;
            }
            set
            {
                selectedValues = value;
            }
        }
        #endregion
        #region ValueEx
        private string valueEx = "";
        [Description("选择项的ValueEx值(多个以','分隔)")]
        public string ValueEx
        {
            get
            {
                if (IsMultiSelect)
                {
                    string str = "";
                    foreach (KeyValuePair<object, string> m in SelectItems)
                    {
                        string strTemp = m.Key.ToString();
                        if (!string.IsNullOrWhiteSpace(strTemp))
                        {
                            strTemp = (str.Equals("") ? "" : ",") + strTemp;
                            str += strTemp;
                        }
                    }
                    return str;
                } 
                return valueEx;
            }
            set
            {
                valueEx = value;                
            }
        }
        #endregion
        #region ItemCheck事件
        //设置CheckBoxList  
        private void list_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            if (e.NewValue == CheckState.Checked)
            {
                if (!SelectItems.ContainsKey(list.SelectedValue))
                {
                    SelectItems.Add(list.SelectedValue, list.Text);
                }                
            }
            else if (e.NewValue == CheckState.Unchecked)
            {
                if (SelectItems.ContainsKey(list.SelectedValue))
                {
                    SelectItems.Remove(list.SelectedValue);
                }
            }
            else
            {
                if (e.NewValue == CheckState.Checked)
                {
                    if (SelectItems.ContainsKey(list.Text))
                    {
                        throw new Exception("手工添加的值中有重复的数据！");
                    }
                    SelectItems.Add(list.Text, list.Text);
                }
                else if (e.NewValue == CheckState.Unchecked)
                {
                    if (SelectItems.ContainsKey(list.Text))
                    {
                        SelectItems.Remove(list.Text);
                    }
                }
            }
        }   //设置ComboBox文本值  
        private void list_MouseUp(object sender, MouseEventArgs e)
        {
            string str = "";

            foreach (KeyValuePair<object, string> m in SelectItems)
            {
                str = str + m.Value + ",";
            }
            this.Text = str.Trim(',');
        }
        //鼠标离开事件
        private void list_MouseLeave(object sender, EventArgs e)
        {
            list.Visible = false;
        }
        #endregion
        #region 重写相关事件
        //点击鼠标  
        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (IsMultiSelect)
            {
                this.DroppedDown = false;
            }
        }
        //释放鼠标
        protected override void OnMouseUp(MouseEventArgs e)
        {
            if (IsMultiSelect)
            {
                this.DroppedDown = false;
            }
        }  //TextChange事件
        protected override void OnTextChanged(EventArgs e)
        {
            if (!list.Visible)
            {
                list.DataSource = null;
                list.Items.Clear();
                SelectItems.Clear();
            }
        }
        //下拉列表事件
        protected override void OnDropDown(EventArgs e)
        {
            if (IsMultiSelect)
            {
                list.Visible = !list.Visible;
                if (list.Visible)
                {
                    list.Focus();
                    list.ItemHeight = this.ItemHeight;
                    list.BorderStyle = BorderStyle.FixedSingle;
                    list.Font = this.Font;
                    list.Size = new Size(this.DropDownWidth, this.ItemHeight * (this.MaxDropDownItems - 1) - (int)this.ItemHeight / 2);
                    list.Location = new Point(this.Left, this.Top + this.ItemHeight + 6);
                    list.BeginUpdate();
                    if (this.DataSource != null)
                    {
                        list.DataSource = this.DataSource;
                        list.DisplayMember = this.DisplayMember;
                        list.ValueMember = this.ValueMember;
                    }
                    list.EndUpdate();
                    if (!this.Parent.Controls.Contains(list))
                    {
                        this.Parent.Controls.Add(list);
                        list.BringToFront();
                    }
                    // 初始化选中项
                    SelectItems.Clear();
                    if (SelectItems.Count < 1 && (!valueEx.Equals("")))
                    {
                        Dictionary<string, string> dictTemp = new Dictionary<string, string>();
                        string strTemp = this.Text;
                        foreach (string strItem in valueEx.Split(','))
                        {
                            dictTemp.Add(strItem.ToLower(), strItem);                            
                        }
                        for (int i = 0; i < list.Items.Count; i++)
                        {
                            list.SelectedIndex = i;                            
                            if (dictTemp.ContainsKey(list.SelectedValue.ToString().ToLower())) { 
                                 list.SetItemChecked(i, true);
                            }
                        }
                        list.SelectedIndex = -1;
                        this.Text = strTemp;
                    }
                }
            }
        }        
        #endregion
    }
}

